home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir41 / tsrsrc35.zip / MARK.ASM < prev    next >
Assembly Source File  |  1993-10-18  |  13KB  |  351 lines

  1. ;==============================================================================
  2. ; MARK.ASM - mark a position in memory,
  3. ;            above which TSRs will later be cleared by RELEASE
  4. ;            MARK can be called multiple times, each RELEASE will clear
  5. ;            above the last MARK called.
  6. ; If MARK is called with something on the command line, that text will
  7. ; be stored in the program segment prefix at offset 80H, where it is
  8. ; later accessible to RELEASE for a "named" release.
  9. ;
  10. ; Syntax:    MARK [/Q] [!][MarkName]
  11. ;==============================================================================
  12. ; written for TASM
  13. ; Copyright (c) 1986,1993 Kim Kokkonen, TurboPower Software.
  14. ; May be freely distributed but not sold except by permission.
  15. ; telephone: 719-260-6641, Compuserve 76004,2611
  16. ;==============================================================================
  17. ; version 1.0  2/8/86
  18. ;     original public release
  19. ;     (thanks to Neil Rubenking for an outline of the method used)
  20. ; :
  21. ; long intervening history
  22. ; :
  23. ; version 3.0  9/24/91
  24. ;   add Quiet option
  25. ;   add code for tracking high memory
  26. ; version 3.1 11/4/91
  27. ;   no change
  28. ; version 3.2 11/22/91
  29. ;   change method of accessing high memory
  30. ;   store parent len as well as parent segment
  31. ; version 3.3 1/8/92
  32. ;   no change
  33. ; version 3.4 2/14/92
  34. ;   no change
  35. ; version 3.5 10/18/93
  36. ;   new hybrid method for finding high memory
  37. ;==============================================================================
  38.  
  39. Cseg    segment public para
  40.         assume  cs:Cseg, ds:Cseg, es:nothing
  41.         locals  @@
  42.  
  43.         org     81H
  44. cmdlin  label   byte                    ;first character of command line
  45.  
  46.         org     100H
  47. comentry: jmp     doit
  48.  
  49. ;put the following in the MAP file
  50. public idstr,vector,egasav,intcom,emscnt,emsmap
  51.  
  52. idstr   db      'MM3.5 TSR'             ;used to find this TSR
  53. firsthimcb dw   0                       ;segment of first mcb in high mem
  54.  
  55. ;**** the following will be overwritten by the vector table image *************
  56. ;success message and version number
  57. didit  db      'MARK 3.5, Copyright 1993 TurboPower Software',13,10
  58. didit2 db      'Marked current memory position',13,10,36
  59. errst  db      'Invalid command line',13,10,36
  60. ;file name for testing EMS presence
  61. emsnm  db      'EMMXXXX0',0
  62. quiet  db      0
  63. xmsadr  label   dword                           ;XMS control address
  64. xmsxxx  dw      2 dup (0)
  65. ;******************************************************************************
  66.  
  67. vector equ     0120H           ;offset in code seg where vector table is copied
  68. veclen equ     0400H           ;1024 bytes for vectors
  69. egasav equ     vector+veclen
  70. egalen equ     8               ;8 bytes for EGA save area
  71. intcom equ     egasav+egalen
  72. intlen equ     10H             ;16 bytes for interapps communication area
  73. parent equ     intcom+intlen
  74. parlen equ     parent+2        ;parent's PSP length
  75. emscnt equ     parlen+2
  76. emsmap equ     emscnt+2
  77. ;mcbcnt and mcbmap actually follow after used portion of emsmap
  78. mcbcnt equ     emsmap+400H     ;count of allocated mcbs
  79. mcbmap equ     mcbcnt+2        ;array of mcb segments
  80. ;newloc follows after the longest possible emsmap and mcbmap
  81. newloc equ     mcbmap+400H     ;location of relocated code
  82.  
  83. ;*****************************************************************************
  84.  
  85. findhidos proc near
  86. ;returns ax = first high mcb, or 0 if none found
  87.         mov     ah,52H                  ;get first mcb segment
  88.         int     21H
  89.         mov     ax,es:[bx-2]            ;ax=first mcb
  90.  
  91.         push    ds
  92.         assume  ds:nothing
  93.  
  94. @@1:    cmp     ax,9FFFH                ;above 640K?
  95.         ja      @@2                     ;jump if so
  96.         mov     ds,ax                   ;ds:[0] points to mcb
  97.         xor     ax,ax                   ;set ax to zero in case we exit here
  98.         cmp     byte ptr ds:[0],'Z'     ;end of mcb chain?
  99.         je      @@2                     ;exit if so
  100.         mov     ax,ds                   ;restore ax to mcb segment
  101.         inc     ax                      ;skip over mcb itself
  102.         add     ax,ds:[3]               ;add length of memory block
  103.         jmp     @@1
  104.  
  105. @@2:    pop     ds                      ;ds = cs
  106.         assume  ds:cseg
  107.         ret
  108. findhidos endp
  109.  
  110. doit   proc    near
  111.  
  112. ;find first mcb in high memory, if any
  113.         mov     ax,5802h
  114.         int     21H                     ;get umb link status
  115.         or      al,al                   ;high memory already linked?
  116.         jz      @@u1                    ;jump if not
  117.  
  118.         call    findhidos               ;find mcb using linked chain
  119.  
  120.         or      ax,ax                   ;valid mcb seg returned?
  121.         jz      @@u9                    ;jump if not
  122.         mov     cx,ax
  123.         jmp     @@9                     ;found first umb
  124.  
  125. @@u1:   mov     ax,5803H
  126.         mov     bx,1
  127.         int     21H                     ;link umb
  128.         jc      @@u9                    ;jump if failed
  129.  
  130.         call    findhidos               ;find mcb using linked chain
  131.  
  132.         push    ax                      ;save result
  133.         mov     ax,5803H
  134.         xor     bx,bx
  135.         int     21H                     ;unlink umb
  136.         pop     ax                      ;restore result
  137.  
  138.         or      ax,ax                   ;valid mcb seg returned?
  139.         jz      @@u9                    ;jump if not
  140.         mov     cx,ax
  141.         jmp     @@9                     ;found first umb
  142.  
  143. @@u9:   mov     ax,3000h                ;get DOS version
  144.         int     21H
  145.         cmp     al,3
  146.         jb      @@7                     ;no XMS driver possible
  147.         mov     ax,4300h
  148.         int     2Fh                     ;multiplex call for XMS
  149.         cmp     al,80h                  ;proper signature?
  150.         jne     @@7                     ;no XMS driver
  151.         mov     ax,4310h                ;get XMS control address
  152.         int     2Fh
  153.         mov     xmsxxx,bx               ;save it
  154.         mov     xmsxxx[2],es
  155.         mov     ah,10h
  156.         mov     dx,0FFFFh
  157.         call    xmsadr                  ;ask to allocate FFFF paras of UMB
  158.         cmp     bl,0B0h                 ;will fail with B0 if UMBs avail
  159.         je      @@0
  160.         cmp     bl,0B1h                 ;will fail with B1 if UMBs all allocated
  161.         jne     @@7                     ;no UMBs exist
  162. @@0:    int     12H
  163.         mov     cl,6
  164.         shl     ax,cl                   ;get segment of top of memory
  165.  
  166. @@1:    mov     es,ax
  167.         cmp     byte ptr es:[0000h],'M' ;potential mcb?
  168.         jnz     @@6                     ;not an mcb, try next segment
  169. @@2:    mov     cx,ax                   ;save potential start mcb in cx
  170. @@3:    inc     ax
  171.         add     ax,es:[0003h]           ;ax = start of next mcb
  172.         jc      @@5                     ;can't be an mcb if we wrapped
  173.         mov     es,ax                   ;address of next mcb
  174.         mov     dl,es:[0000h]
  175.         cmp     dl,'M'
  176.         jz      @@3                     ;good start mcb
  177.         cmp     dl,'Z'
  178.         jz      @@9                     ;good end mcb
  179. @@5:    mov     ax,cx                   ;restore last start segment
  180. @@6:    cmp     ax,0FFFFh               ;top of memory?
  181.         je      @@7
  182.         inc     ax                      ;try next segment
  183.         jmp     @@1
  184.  
  185. @@7:    xor     cx,cx                   ;no matching UMB
  186. @@9:    mov     firsthimcb,cx           ;store first high mcb
  187.  
  188. ;relocate ourselves out of the way
  189.         push    cs
  190.         pop     es
  191.         mov     di,newloc
  192.         push    di                      ;will act as a return address
  193.         mov     si,offset parse
  194.         mov     cx,lastcode-parse
  195.         cld
  196.         rep     movsb
  197.         ret                             ;"return" to the relocated code
  198.  
  199. ;scan command line for /Q option
  200. parse:  mov     si,offset cmdlin
  201.         cld
  202. get1:   lodsb
  203.         cmp     al,13                   ;end of command line?
  204.         je      pmess
  205.         cmp     al,'/'                  ;option switch?
  206.         je      getop
  207.         cmp     al,'-'
  208.         jne     get1                    ;loop around
  209. getop:  mov     di,si                   ;save option position
  210.         lodsb
  211.         cmp     al,'a'
  212.         jb      noup
  213.         cmp     al,'z'
  214.         ja      noup
  215.         and     al,0DFH                 ;uppercase
  216. noup:   cmp     al,'Q'
  217.         jne     error
  218.         mov     quiet,1                 ;set quiet flag
  219.         dec     di
  220.         mov     al,' '
  221.         stosb                           ;clear option
  222.         stosb
  223.         jmp     get1                    ;loop around
  224.  
  225. error:  mov     dx,offset errst
  226.         mov     ah,9
  227.         int     21H
  228.         mov     ax,4C01H
  229.         int     21H
  230.  
  231. ;print message if not quiet
  232. pmess:  cmp     quiet,0
  233.         jnz     chkems
  234.         mov     dx,offset didit
  235.         mov     ah,9
  236.         int     21H                     ;write success message
  237.  
  238. ;determine whether EMS is present
  239. chkems: mov     dx,offset emsnm
  240.         mov     ax,3D00H
  241.         int     21H
  242.         jnc     emspres                 ;EMS driver installed
  243.         xor     bx,bx
  244.         jmp     short stocnt
  245.  
  246. ;EMS present, close the open handle first
  247. emspres:
  248.         mov     bx,ax
  249.         mov     ah,3EH
  250.         int     21H
  251.  
  252. ;store the EMS page map
  253.         mov     ah,4DH
  254.         mov     di,emsmap
  255.         xor     bx,bx                   ;required by some versions of EMM
  256.         cld                             ;required by some versions of EMM
  257.         int     67H
  258.  
  259. ;store the number of active EMS handles
  260. stocnt:
  261.         mov     ds:[emscnt],bx          ;count of active handles
  262.  
  263. ;store the interrupt vector table (overwrites initial messages)
  264.         xor     ax,ax
  265.         mov     ds,ax                   ;source address segment 0
  266.         assume  ds:nothing
  267.         xor     si,si                   ;offset 0
  268.         mov     di,vector               ;destination offset, es=cs already
  269.         mov     cx,veclen shr 1         ;count of words to store
  270.         rep     movsw                   ;copy vectors to our table
  271.  
  272. ;store the EGA save area
  273.         mov     ax,40H
  274.         mov     ds,ax                   ;point to BIOS data area
  275.         mov     si,00A8H                ;EGA save area pointer
  276.         mov     di,egasav
  277.         mov     cx,egalen shr 1
  278.         rep     movsw                   ;copy information to our save area
  279.  
  280. ;store the interapplications communication area
  281.         mov     si,00F0H                ;interapps communication area address
  282.         mov     di,intcom
  283.         mov     cx,intlen shr 1
  284.         rep     movsw                   ;copy information to our save area
  285.  
  286. ;store the parent's PSP segment
  287.         push    cs
  288.         pop     ds                      ;ds = cs
  289.         assume  ds:cseg
  290.         mov     ax,ds:[16h]             ;get parent's PSP from our PSP
  291.         mov     ds:[parent],ax          ;store in data save area
  292.         dec     ax
  293.         mov     es,ax
  294.         mov     ax,es:[0003h]           ;get length of parent's psp
  295.         mov     ds:[parlen],ax          ;store in data save area
  296.  
  297. ;store the mcb chain
  298.         mov     ah,52H                  ;get first mcb segment
  299.         int     21H
  300.         mov     ax,es:[bx-2]            ;ax=first mcb
  301.         push    cs
  302.         pop     es                      ;es=cs
  303.  
  304.         mov     di,cs:[emscnt]          ;get starting address of mcbmap
  305.         shl     di,1
  306.         shl     di,1
  307.         add     di,emsmap
  308.         mov     si,di                   ;cs:[si] -> mcbcnt
  309.         add     di,2                    ;cs:[di] -> mcbmap
  310.         xor     cx,cx                   ;cx will count mcbs
  311.         cld
  312.         push    ds
  313.         assume  ds:nothing
  314.  
  315. mcbnext:
  316.         stosw                           ;store mcb segment held by ax
  317.         mov     ds,ax                   ;ds:[0] points to mcb
  318.         mov     ax,ds:[1]               ;get mcb owner
  319.         stosw                           ;store it
  320.         inc     cx                      ;increment count
  321.         cmp     byte ptr ds:[0],'Z'     ;end of mcb chain?
  322.         je      mcbdone
  323.         mov     ax,ds                   ;restore ax to mcb segment
  324.         inc     ax                      ;skip over mcb itself
  325.         add     ax,ds:[3]               ;add length of memory block
  326.         jmp     mcbnext
  327.  
  328. mcbdone:mov     ax,firsthimcb           ;check for high memory
  329.         or      ax,ax
  330.         jz      mcbend
  331.         mov     firsthimcb,0            ;only do it once
  332.         jmp     mcbnext
  333.  
  334. mcbend: pop     ds
  335.         assume  ds:cseg
  336.  
  337. ;terminate and stay resident
  338. gores:  mov     [si],cx                 ;store mcbcnt
  339.         mov     dx,di                   ;dx = past last used mcb segment
  340.         add     dx,000FH                ;add paragraph roundup
  341.         mov     cl,4
  342.         shr     dx,cl                   ;convert to paragraphs
  343.         mov     ax,3100H
  344.         int     21H                     ;terminate but stay resident
  345.  
  346. lastcode:
  347. doit    endp
  348.  
  349. Cseg    ends
  350.         end     ComEntry
  351.